package com.kelvem.saas.workbanch.core.manager.controller;

import com.kelvem.saas.workbanch.core.base.Page;
import com.kelvem.saas.workbanch.core.exception.SaasAssert;
import com.kelvem.saas.workbanch.core.manager.service.GraphqlService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * 实体控制层
 *
 * @author kelvem
 * @version 1.0
 */
@RestController
@Slf4j
@RequestMapping("/graphql")
public class GraphqlController {

    @Resource
    private GraphqlService graphqlService;
    
    /**
     * 查询实体列表数据
     * curl -X POST http://localhost:9090/graphql/meta_table/v1/queryList -H 'Content-Type: application/json' -d '{"id": 999}'
     *
     * @param tableName 表名
     * @param queryVo 查询用
     * @return Page<Entity> 实体列表数据
     */
    @PostMapping("/{tableName}/v1/queryList")
    public List<Map<String, Object>> queryList(@PathVariable(required = false) String tableName, @RequestBody(required = false) Map<String, Object> queryVo) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(queryVo);
        
        log.debug("GraphqlController:queryList:start, tableName={}, queryVo=【{}】", tableName, queryVo);
        List<Map<String, Object>> list = graphqlService.queryEntityList(tableName, queryVo);
        log.debug("GraphqlController:queryList:end, page.count={}", list.size());
        
        return list;
    }

    /**
     * 查询实体分页数据
     * curl -X POST http://localhost:9090/graphql/yy_orders/v1/queryPage -H 'Content-Type: application/json' -d '{"id": 999}'
     *
     * @param tableName 表名
     * @param queryVo 查询用
     * @return Page<Entity> 实体分页数据
     */
    @PostMapping("/{tableName}/v1/queryPage")
    public Page<Map<String, Object>> queryPage(@PathVariable(required = false) String tableName, @RequestBody(required = false) Map<String, Object> queryVo) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(queryVo);

        log.debug("GraphqlController:queryPage:start, tableName={}, queryVo=【{}】", tableName, queryVo);
        Page<Map<String, Object>> page = graphqlService.queryEntityPage(tableName, queryVo);
        log.debug("GraphqlController:queryPage:end, page.count={}", page.getSize());

        return page;
    }

    /**
     * 根据id查实体信息
     * curl -X GET 'http://localhost:9090/graphql/meta_table/v1/get/999'
     *
     * @param id 实体id
     * @return Graphql 实体信息
     */
    @GetMapping("/{tableName}/v1/get/{id}")
    public Map<String, Object> getById(@PathVariable(required = false) String tableName, @PathVariable(required = false) Long id) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(id);

        log.debug("GraphqlController:getById:start, tableName={}, id={}", tableName, id);
        Map<String, Object> entity = graphqlService.getEntityById(tableName, id);
        log.debug("GraphqlController:getById:end, graphql=【{}】", entity);

        return entity;
    }

    /**
     * 新增实体分页数据
     * curl -X POST http://localhost:9090/graphql/meta_table/v1/add -H 'Content-Type: application/json' -d '{"id": 999}'
     *
     * @param tableName 表名
     * @param entity 实体
     * @return 主键id
     */
    @PostMapping("/{tableName}/v1/add")
    public Integer add(@PathVariable(required = false) String tableName, @RequestBody(required = false) Map<String, Object> entity) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(entity);

        log.debug("GraphqlController:add:start, tableName={}, queryVo=【{}】", tableName, entity);
        Integer n = graphqlService.addEntity(tableName, entity);
        log.debug("GraphqlController:add:end, add.count={}", n);

        return n;
    }

    /**
     * 保存实体分页数据
     * curl -X PUT http://localhost:9090/graphql/meta_table/v1/update -H 'Content-Type: application/json' -d '{"id": 999}'
     *
     * @param tableName 表名
     * @param entity 实体
     * @return 主键id
     */
    @PostMapping("/{tableName}/v1/update")
    public Integer update(@PathVariable(required = false) String tableName, @RequestBody(required = false) Map<String, Object> entity) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(entity);

        log.debug("GraphqlController:edit:start, tableName={}, queryVo=【{}】", tableName, entity);
        Integer n = graphqlService.updateEntity(tableName, entity);
        log.debug("GraphqlController:edit:end, add.count={}", n);

        return n;
    }

    /**
     * 保存实体分页数据
     * curl -X POST http://localhost:9090/graphql/meta_table/v1/batchAddUpdate -H 'Content-Type: application/json' -d '{"id": 999}'
     *
     * @param tableName 表名
     * @param entityList 实体列表
     * @return 影响数量
     */
    @PostMapping("/{tableName}/v1/batchAddUpdate")
    public Integer batchAddUpdateEntity(@PathVariable(required = false) String tableName, @RequestBody(required = false) List<Map<String, Object>> entityList) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(entityList);

        log.debug("GraphqlController:batchAddEntity:start, tableName={}, queryVo=【{}】", tableName, entityList);
        Integer n = graphqlService.batchAddUpdateEntity(tableName, entityList);
        log.debug("GraphqlController:batchAddEntity:end, add.count={}", n);

        return n;
    }

    /**
     * 根据id删除实体信息
     * curl -X DELETE 'http://localhost:9090/graphql/meta_table/v1/delete/999'
     *
     * @param tableName 表名
     * @param id 实体id
     * @return Graphql 实体信息
     */
    @PostMapping("/{tableName}/v1/delete/{id}")
    public Integer deleteEntity(@PathVariable(required = false) String tableName, @PathVariable(required = false) Long id) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(id);

        log.debug("GraphqlController:deleteEntity:start, tableName={}, id={}", tableName, id);
        Integer count = graphqlService.deleteEntity(tableName, id);
        log.debug("GraphqlController:deleteEntity:end, count=【{}】", count);

        return count;
    }

    /**
     * 查询key-value数据
     * curl -X POST http://localhost:9090/graphql/yy_orders/v1/keyValue?key=id&value=order_no&query=1 -H 'Content-Type: application/json'
     *
     * @param tableName 表名
     * @param key key字段
     * @param value value字段
     * @param query 查询值
     * @param limit 数据量
     * @return List<Map<String, String>> key-value数据
     */
    @PostMapping("/{tableName}/v1/keyValue")
    public List<Map<String, String>> keyValue(
            @PathVariable(required = false) String tableName,
            @RequestParam(required = false) String key,
            @RequestParam(required = false) String value,
            @RequestParam(required = false) String query,
            @RequestParam(required = false) Integer limit) {
        SaasAssert.notNull(tableName);
        SaasAssert.notNull(key);
        SaasAssert.notNull(value);
        if (limit == null) {
            limit = 10;
        }

        log.debug("GraphqlController:keyValue:start, tableName={}, key=【{}】", tableName, key);
        List<Map<String, String>> list = graphqlService.keyValue(tableName, key, value, query, limit);
        log.debug("GraphqlController:keyValue:end, list.count={}", list.size());

        return list;
    }

    /**
     * replace mapping表数据(废弃)
     *
     * @param tableName 表名
     * @param srcId 源id
     * @param targetIdList 目标ids
     * @param srcColumn 源字段名
     * @param targetColumn 目标字段名
     * @return 影响数据条数
     */
    @PostMapping("/{tableName}/v1/replaceMapping")
    public Integer replaceMapping(
            @PathVariable(required = false) String tableName,
            @RequestParam(required = false) Long srcId,
            @RequestParam(required = false) List<Long> targetIdList,
            @RequestParam(required = false) String srcColumn,
            @RequestParam(required = false) String targetColumn) {

        SaasAssert.notNull(tableName);
        SaasAssert.notNull(srcId);

        log.debug("GraphqlController:replaceMapping:start, tableName={}, srcId=【{}】, targetIdList=【{}】", tableName, srcId, targetIdList);
        Integer cnt = graphqlService.replaceMapping(tableName, srcId, targetIdList, srcColumn, targetColumn);
        log.debug("GraphqlController:replaceMapping:end, cnt={}", cnt);
        return cnt;
    }
}

